Swift – Identify misspelled words and errors in phrases

A simple tutorial for find and identify the wrong typed words of the user in your application using the UITextChecker framework and the NatualLanguage framework.

Final result:

Let’s start!

We use for this tutorial the following new things:

NaturalLanguage framework (reference)

NLLanguageRecognizer (reference)

UITextChecker (reference)

In order to identify the wrong words in your phrase, you need to understand the language of the phrase.

NLLanguageRecognizer helps you to resolve this issue in a very simple way:

private func detectLanguage( phrase: String ) -> NLLanguage? {
let recognizer = NLLanguageRecognizer()
recognizer.processString(phrase)
return recognizer.dominantLanguage
}

You can pass a phrase on it and get the corresponding language.

let phrase = "This si a text wiht lots of errrors. The scope of this tutorila is to colorizze the wrong wordss."

let phraseLanguage: NLLanguage? = detectLanguage( phrase: phrase )
print( phraseLanguage )

Now we need to check all the words and get, the wrong list words or the range of the words (use it for NSAttributedStrings for instance)

I’ve created a simple struct and a simple checker function, like these:

struct Words {
var range: NSRange?
var word: String
}

And we use it in the checker:

private func checkMispelledWords( phrase: String ) -> [Words] {
var rangesOfWords: [Words] = [Words]()

let phraseLanguage: NLLanguage? = detectLanguage( phrase: phrase )
guard let language = phraseLanguage else { return rangesOfWords }

let textChecker = UITextChecker()
let nsString = NSString(string: phrase)
let stringRange = NSRange(location: 0, length: nsString.length)
var offset = 0

while true {
let wordRange = textChecker.rangeOfMisspelledWord(
in: phrase,
range: stringRange,
startingAt: offset,
wrap: false,
language: language.rawValue)

guard wordRange.location != NSNotFound else { break }

let wrongWord = nsString.substring(with: wordRange)
offset = wordRange.upperBound

rangesOfWords.append( Words(range: wordRange, word: wrongWord) )
}
return rangesOfWords
}

Now we have a new [Word] array with our data:

let words: [Words] = checkMispelledWords(
phrase: textArea.attributedText.string)

If you add a button and a textarea in your app you can attach the attributed string and play with the attributes:

@IBAction func didCheckErrorsPressed(_ sender: Any) {
let words: [Words] = checkMispelledWords(phrase: textArea.attributedText.string)

words.forEach {
print( "Word: ($0.word)" )
attributedString?.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red , range: $0.range!)
}

textArea.attributedText = attributedString
}

Now you can “coloryze” your text to make the errors in red.

Enjoy writing!